/*
 * GeoVISTA Center (Penn State, Dept. of Geography)
 * Copyright (c), 2002, GeoVISTA Center
 * Licensed under Simplified BSD License
 * This library is developed and distributed for free usage,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 * You can redistribute and/or modify it under the terms of the
 * Simplified BSD License
 *
 *
 *
 *
 *
 *
*
*
* @Original Author: jin Chen
* @date: Dec 13, 2004$
* @version: 1.0
*/
package edu.psu.geovista.app.visualclassifier.classify.v2.gui;

import edu.psu.geovista.app.visualclassifier.classify.v2.Attribute;
import edu.psu.geovista.app.visualclassifier.classify.v2.DefaultESVisualClassifier;
import edu.psu.geovista.app.visualclassifier.classify.v2.ESVisualClassifier;
import edu.psu.geovista.app.visualclassifier.classify.v2.UnsupervisedSettingTaskFactory;
import edu.psu.geovista.classification.setting.ClassifySetting;
import edu.psu.geovista.classification.setting.ClassifySetting1D;
import edu.psu.geovista.classification.setting.ClassifySetting2D;
import edu.psu.geovista.classification.setting.ClassifySettingSwitch;
import edu.psu.geovista.common.awt.event.dataloading.AppDataEvent;
import edu.psu.geovista.data.model.AppDataModel;
import edu.psu.geovista.io.util.MyFileFilter;
import edu.psu.geovista.jdm.JDMUtils;
import edu.psu.geovista.jdm.algorithms.BoundaryClassificationSettings;
import edu.psu.geovista.jdm.algorithms.KMeansSettings;
import edu.psu.geovista.jdm.base.JDMUnsupervisedAlgorithm;
import edu.psu.geovista.jdm.base.JDMUnsupervisedAlgorithmSettings;
import edu.psu.geovista.jdm.base.JDMUnsupervisedSettings;
import edu.psu.geovista.jdm.base.JDMUnsupervisedTask;
import edu.psu.geovista.jdm.gui.UnsupervisedSettingsGUI;
import edu.psu.geovista.ui.event.DataSetEvent;
import edu.psu.geovista.ui.event.DataSetListener;

import javax.swing.*;
import javax.swing.border.TitledBorder;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;


public class EsUnsupervisedSettingsGUI extends UnsupervisedSettingsGUI
        implements DataSetListener{

    public static final String CLASSIFY_ALL_ATTRIBUTES="All variables";

    private String [] attrNames;
    private AppDataModel dataModel;
    protected JPanel radioPanel;
    protected JPanel controlPane;
    ESVisualClassifier vc;

    public EsUnsupervisedSettingsGUI() {
        super();
        this.setComponents();
        this.setNames(this);
    }
    /*******************************************************************************************************
     *                classify
     *******************************************************************************************************/
     /**
     *  
     */
    public void fireAction(){
       /* ClassifySetting settings = getClassifySetting();
        if(settings!=null)
            vc.classify(settings);*/
       //((DefaultESVisualClassifier)vc).classifyGUISetting();
         if(vc!=null)
            vc.classifyOnGUISetting();
    }

    /**
     * do classification and update GUI based on given ClassifySetting.
     * instead of put the method in vc,  put it in GUI enable auto update GUI component
     * @param settings
     */
    public void setClassifySetting(ClassifySetting settings){
        if(settings instanceof ClassifySetting1D){
            setClsSetting((ClassifySetting1D)settings); //update GUI
            //doClassification();
            //this.fireAction();   
           // vc.classify(settings);// 
        }
        else if (settings instanceof ClassifySetting2D){//not implement as not see such scenoria exist
            /*  setClassifySetting((ClassifySetting2D)settings);
            this.fireAction();*/
        }
        else if(settings instanceof ClassifySettingSwitch) {
            setClsSetting((ClassifySettingSwitch) settings);

            
        }

    }
    public void selectVariable(String varname){
        this.uniAttrSel.setSelectedItem(varname);

    }
    public void selectVariable(int index){
        this.uniAttrSel.setSelectedIndex(index);

    }

    /**
     * switch classification types
     * @param setting
     */
    private void setClsSetting(ClassifySettingSwitch setting ){
        int numV = setting.getNumOfVariable();
        if(numV==ClassifySettingSwitch.UNI_VAR ){
            this.uniButton.setSelected(true);
            this.uniButton.doClick();
        }
        else if(numV==ClassifySettingSwitch.BI_VAR ){
            /*String yvarname = setting.getYvarname();
            if(yvarname!=null){//bi-var classification is to made based on this y variable
                biAttrSel2.setSelectedItem(yvarname);
            }*/
            this.biButton.setSelected(true);
            biButton.doClick();
        }
        else if(numV==ClassifySettingSwitch.MULTI_VAR){
            this.multiButton.setSelected(true);
            multiButton.doClick();
        }

        //doClassification();
    }

    /**
     *  
     * @param setting
     */
    private void setClsSetting(ClassifySetting1D setting){

        String classifier = setting.getClassifier();
        if(classifier!=null)this.uniClassifier.setSelectedItem(classifier);  // 

        int ctgCount = setting.getNumOfCategory();
        if(ctgCount>0) this.uniNumc.setValue(new Integer(ctgCount));

        String varname = setting.getVariableName();
        String ctype = getClassifyType();
        if(ctype==null)return;//initially

        if(ctype.equals(UnsupervisedSettingsGUI.uniString) ){ //currently GUI is set as  ui-var classification
            String dn = setting.getDimensionName();
            String vn = setting.getVariableName();

            if(dn.equals(ClassifySetting1D.DIMENSION_NAME_X)){
                // 
                this.uniAttrSel.setSelectedItem(vn);
            }
        }
        else if (ctype.equals(UnsupervisedSettingsGUI.biString) ){  //2D , use ClassifySetting1D because of LegendControl will update one variable at a time
            System.err.println("incomplete, need update GUI based on given setting ");
           // biClassifier1.
            //in this case, both variable can be set
            String dn = setting.getDimensionName();
            String vn = setting.getVariableName();
            if(dn.equals(ClassifySetting1D.DIMENSION_NAME_X)){//on the legendControl,  update 1st variable list
                // 
                this.biAttrSel1.setSelectedItem(vn);
            }
            else{ //on the legendControl,  update 2nd variable list
                this.biAttrSel2.setSelectedItem(vn);
            }

        }

    }
    private void setClassifySetting(ClassifySetting2D setting){

       /* String classifierX = setting.getxClassifier();// getClassifier();
        if(classifierX!=null )this.biClassifier1.setSelectedItem(classifierX);
        String classifierY = setting.getyClassifier();
        if(classifierY!=null ) this.biClassifier2.setSelectedItem(classifierY);

        int ctgcountX = setting.getxNumOfCategory();
        int ctgcountY = setting.getyNumOfCategory();
        this.biNumc1.setValue(new Integer(ctgcountX));
        this.biNumc2.setValue(new Integer(ctgcountY));

        int type = setting.getType();
        String ctype = getClassifyType();

        if (ctype.equals(UnsupervisedSettingsGUI.biString) ){  //2D
            //in this case, both variable can be set
            //String dn = setting..getDimensionName();
            String xvn = setting.getxVariableName();
            if(xvn!=null)    this.biAttrSel1.setSelectedItem(xvn);
            String yvn = setting.getyVariableName();
            if(yvn!=null)this.biAttrSel2.setSelectedItem(yvn);
        }*/
        // this.doClassification();

    }

    /* int type = setting.getType();
    switch(type){
        case ClassifySetting.TYPE_BOUNDARY:
        case ClassifySetting.TYPE_NUM_OF_CATEGORY:
        case ClassifySetting.TYPE_VARIABLE:
            String ctype = getClassifyType();
            if(ctype==null)return;//initially
            if(ctype.equals(UnsupervisedSettingsGUI.uniString) ){ //currently GUI is set as  ui-var classification
                String dn = setting.getDimensionName();
                String vn = setting.getVariableName();
                if(dn.equals(ClassifySetting1D.DIMENSION_NAME_X)){
                    // 

                    this.uniAttrSel.setSelectedItem(vn);
                    this.doClassification();

                }
                else{  // 
                    //in case of y variable , do nothing
                }

            }
            else if (ctype.equals(UnsupervisedSettingsGUI.biString) ){  //2D
                //in this case, both variable can be set
                String dn = setting.getDimensionName();
                String vn = setting.getVariableName();
                if(dn.equals(ClassifySetting1D.DIMENSION_NAME_X)){
                    // 
                    this.biAttrSel1.setSelectedItem(vn);


                }
                else{ this.biAttrSel2.setSelectedItem(vn);
                }
                 this.doClassification();
            }
        default:
            break;

    }*/




    /**
     *  
     * @return
     */
    public ClassifySetting getClassifySetting(){
        if(getDataModel() ==null){
            return null;
        }

        String[] cName = new String[2];
        int[] nc = new int[2], attIdx = new int[2];
        JDMUnsupervisedAlgorithmSettings[] uas = new JDMUnsupervisedAlgorithmSettings[2];
        JDMUnsupervisedSettings settings;
        JDMUnsupervisedTask task;
        Object[] objs;
        String[] selectedAttNames;;//,
        String []  attNames =attrNames;// (String[])dataset[0];

        int type = 0;
        if (uniButton.isSelected()) type = 1;
        else if (biButton.isSelected()) type = 2;
        else if (multiButton.isSelected()) type = 3;

        switch (type) {
            case 1:
                //attIdx[0] = uniAttrSel.getSelectedIndex();
                String attrName=(String) uniAttrSel.getSelectedItem();
                cName[0] = ((String)uniClassifier.getSelectedItem()).trim(); //classify method name
                nc[0] = Integer.parseInt(uniNumc.getValue().toString()); //num of classification

                uas[0] = new BoundaryClassificationSettings(cName[0], nc[0]);
                objs = new Object[2];
                selectedAttNames = new String[1];
                //selectedAttNames[0] = attNames[attIdx[0]];
                selectedAttNames[0] = attrName;//attNames[attIdx[0]];
                objs[0] = selectedAttNames;
                //objs[1] = dataset[attIdx[0] + 1];
                //int colIndex = getDataModel().getColumnIndexByName(attrName);
                //objs[1] = getDataModel().getColumnValueAsDouble(colIndex);  // 

                //Attribute att=new Attribute(selectedAttNames[0] ,objs[1]);   //,dataset[attIdx[0] + 1]
                ClassifySetting1D cs = new ClassifySetting1D(selectedAttNames[0],nc[0],cName[0],null);
                cs.setDimensionName(ClassifySetting1D.DIMENSION_NAME_X);
                // 
                String classifier = cs.getClassifier();
                if(classifier.equals(JDMUnsupervisedAlgorithm.SELF_DEFINED) ){
                    double[] bound =vc.getLegendPlot().getBoundariesUnivar();
                    cs.setBoundaries(bound);
                }

                return cs;

            case 2:

                String attrName1=(String)biAttrSel1.getSelectedItem() ;
                String attrName2=(String)biAttrSel2.getSelectedItem() ;

                cName[0] = ((String)biClassifier1.getSelectedItem()).trim();
                cName[1] = ((String)biClassifier2.getSelectedItem()).trim();
                nc[0] = Integer.parseInt(biNumc1.getValue().toString());
                nc[1] = Integer.parseInt(biNumc2.getValue().toString());
                uas[0] = new BoundaryClassificationSettings(cName[0], nc[0]);
                uas[1] = new BoundaryClassificationSettings(cName[1], nc[1]);
                objs = new Object[3];
                selectedAttNames = new String[2];
                selectedAttNames[0] =attrName1;// attNames[attIdx[0]];
                selectedAttNames[1] =attrName2;// attNames[attIdx[1]];

                int col1Index = getDataModel().getColumnIndexByName(attrName1);
                objs[1] = getDataModel().getColumnValueAsDouble(col1Index);
                int col2Index = getDataModel().getColumnIndexByName(attrName2);
                objs[2] = getDataModel().getColumnValueAsDouble(col2Index);

                objs[0] = selectedAttNames;
                double[] boundx=null;
                if(cName[0].equals(ClassifySetting.SELF_DEFINED) ){
                    ClassifySetting1D setting = (ClassifySetting1D) vc.getClassifySettings().get(selectedAttNames[0]);
                    if (setting!=null)boundx=setting.getBoundaries();
                }
                double[] boundy=null;
                if(cName[1].equals(ClassifySetting.SELF_DEFINED) ){
                    ClassifySetting1D setting = (ClassifySetting1D) vc.getClassifySettings().get(selectedAttNames[1]);
                    if (setting!=null)boundy=setting.getBoundaries();
                }
                ClassifySetting2D cs2 = new ClassifySetting2D(selectedAttNames[0],nc[0],cName[0],boundx,
                        selectedAttNames[1],nc[1],cName[1],boundy  );
                return cs2;

            case 3:
                task=null;
                cName[0] = ((String)multiClassifier.getSelectedItem()).trim();
                nc[0] = Integer.parseInt(multiNumc.getValue().toString());
                if (cName[0].compareTo("KMeans") == 0)
                    uas[0] = new KMeansSettings(cName[0], nc[0], null);
                Object[] dataset = new java.lang.Object[0];
                try {
                    dataset = this.getDataModel().getGeoVistaRawData();
                } catch (Exception e) {
                    e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
                    break;
                }
                objs = JDMUtils.getSelectedObjs(dataset, mvAttIndices);
                settings = new JDMUnsupervisedSettings(type, uas, objs);
                task = new JDMUnsupervisedTask(settings);
                break;
            default:
                System.out.println("getUnsupervisedTask: unknown number of variables");
                task = null;
                break;
        }
        return null;
    }

    public JDMUnsupervisedTask getUnsupervisedTask() {

        String[] cName = new String[2];
        int[] nc = new int[2], attIdx = new int[2];
        JDMUnsupervisedAlgorithmSettings[] uas = new JDMUnsupervisedAlgorithmSettings[2];
        JDMUnsupervisedSettings settings;
        JDMUnsupervisedTask task;
        Object[] objs;
        String[] selectedAttNames;;//,
        String []  attNames =attrNames;// (String[])dataset[0];

        int type = 0;
        if (uniButton.isSelected()) type = 1;
        else if (biButton.isSelected()) type = 2;
        else if (multiButton.isSelected()) type = 3;

        switch (type) {
            case 1:
                //attIdx[0] = uniAttrSel.getSelectedIndex();
                String attrName=(String) uniAttrSel.getSelectedItem();
                cName[0] = ((String)uniClassifier.getSelectedItem()).trim(); //classify method name
                nc[0] = Integer.parseInt(uniNumc.getValue().toString()); //num of classification
                uas[0] = new BoundaryClassificationSettings(cName[0], nc[0]);
                objs = new Object[2];
                selectedAttNames = new String[1];
                //selectedAttNames[0] = attNames[attIdx[0]];
                selectedAttNames[0] = attrName;//attNames[attIdx[0]];
                objs[0] = selectedAttNames;
                //objs[1] = dataset[attIdx[0] + 1];
                int colIndex = getDataModel().getColumnIndexByName(attrName);
                objs[1] = getDataModel().getColumnValueAsDouble(colIndex);  // 

                Attribute att=new Attribute(selectedAttNames[0] ,objs[1]);   //,dataset[attIdx[0] + 1]
                return UnsupervisedSettingTaskFactory.getUniTask(att,cName[0],nc[0]);

            case 2:
                //attIdx[0] = biAttrSel1.getSelectedIndex();
                //attIdx[1] = biAttrSel2.getSelectedIndex();
                String attrName1=(String)biAttrSel1.getSelectedItem() ;
                String attrName2=(String)biAttrSel2.getSelectedItem() ;

                cName[0] = ((String)biClassifier1.getSelectedItem()).trim();
                cName[1] = ((String)biClassifier2.getSelectedItem()).trim();
                nc[0] = Integer.parseInt(biNumc1.getValue().toString());
                nc[1] = Integer.parseInt(biNumc2.getValue().toString());
                uas[0] = new BoundaryClassificationSettings(cName[0], nc[0]);
                uas[1] = new BoundaryClassificationSettings(cName[1], nc[1]);
                objs = new Object[3];
                selectedAttNames = new String[2];
                selectedAttNames[0] =attrName1;// attNames[attIdx[0]];
                selectedAttNames[1] =attrName2;// attNames[attIdx[1]];

                int col1Index = getDataModel().getColumnIndexByName(attrName1);
                objs[1] = getDataModel().getColumnValueAsDouble(col1Index);
                int col2Index = getDataModel().getColumnIndexByName(attrName2);
                objs[2] = getDataModel().getColumnValueAsDouble(col2Index);

                objs[0] = selectedAttNames;
                /*objs[1] = dataset[attIdx[0] + 1];
                objs[2] = dataset[attIdx[1] + 1];*/

                Attribute att1=new Attribute(selectedAttNames[0] ,objs[1]);//dataset[attIdx[0] + 1]);
                Attribute att2=new Attribute(selectedAttNames[1] ,objs[2]);//dataset[attIdx[1] + 1]);
                return UnsupervisedSettingTaskFactory.getBiTask(att1,cName[0],nc[0],att2,cName[1],nc[1]);
                //settings = new JDMUnsupervisedSettings(2, uas, objs);
                //task = new JDMUnsupervisedTask(settings);
                //break;
            case 3:
                task=null;
                cName[0] = ((String)multiClassifier.getSelectedItem()).trim();
                nc[0] = Integer.parseInt(multiNumc.getValue().toString());
                if (cName[0].compareTo("KMeans") == 0)
                    uas[0] = new KMeansSettings(cName[0], nc[0], null);
                Object[] dataset = new java.lang.Object[0];
                try {
                    dataset = this.getDataModel().getGeoVistaRawData();
                } catch (Exception e) {
                    e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
                    break;
                }
                objs = JDMUtils.getSelectedObjs(dataset, mvAttIndices);
                settings = new JDMUnsupervisedSettings(type, uas, objs);
                task = new JDMUnsupervisedTask(settings);
                break;
            default:
                System.out.println("getUnsupervisedTask: unknown number of variables");
                task = null;
                break;
        }
        return task;

    }

    /* public void doClassification(){
        this.fireAction();
    }*/

    public void setDataSet(Object[] dataSetIn) {
        dataset = dataSetIn;
        mvAttIndices = null;
        if (dataset != null) {
            setAttrList((String[])dataset[0]);
            attSelPanel.setAttList(JDMUtils.makeAttList(dataset, true), mvAttIndices);
            fireAction();
        }
    }
    public void setDataModel(edu.psu.geovista.data.model.AppDataModel dataModel) {
        //this.setDataModel((AppDataModel) dataModel);
        this.dataModel = dataModel;
        attrNames = dataModel.getColumnNames();
        //Object[] raw = dataModel.getRaw();
        //this.dataset =raw;
        //this.setd
        this.setAttrList(attrNames);

    }
    /*  public void setDataModel(AppDataModel dataModel) {
        this.dataModel = dataModel;
    }*/

    private void setAttrList(String [] attrNames) {
        //String[] attrNames = (String[])dataset[0];
        DefaultComboBoxModel uniModel = new DefaultComboBoxModel(attrNames);
        uniModel.insertElementAt(CLASSIFY_ALL_ATTRIBUTES,0);//1st choice is classify all variables
        uniAttrSel.setModel(uniModel);

        DefaultComboBoxModel biModel1 = new DefaultComboBoxModel(attrNames);
        biAttrSel1.setModel(biModel1);
        DefaultComboBoxModel biModel2 = new DefaultComboBoxModel(attrNames);
        biAttrSel2.setModel(biModel2);
    }
    private void setNames(Object container){
        java.lang.reflect.Field fields[]= container.getClass().getDeclaredFields();
        for(int i=0;i<fields.length ;i++){
            java.lang.reflect.Field fd=fields[i];
            Class fdtype=fd.getType() ;
            if(JComponent.class.isAssignableFrom(fdtype )){//if the field is JComponent
                //System.out.println("Find JComponent field:"+fd.getName() +":"+fdtype.getName() ) ;
                try{
                    //Object obj=new Object();
                    //JComponent comp=getComp(fdtype.getName());
                    JComponent comp=(JComponent)fd.get(container);// 
                    if(comp!=null&&fd!=null)
                    comp.setName( fd.getName() );//comp: the instance vairable object represented by the field
                    //System.out.println("comp.getName():"+comp.getName() );
                }
                catch(Exception e){
                    e.printStackTrace() ;
                }
            }
        }
    }

    /*******************************************************************************************************
     *                events
     *******************************************************************************************************/
    /**
     *
     * @param e
     */
    public void dataSetChanged(DataSetEvent e) {
        Object[] data=e.getDataSet() ;
        if(e instanceof AppDataEvent){
            AppDataEvent ae=(AppDataEvent) e;
            AppDataModel dataModel=ae.getDataModel() ;
            if(dataModel!=null){
                setDataModel(dataModel);
                return;
            }
        }

        setDataSet(data);
    }

    /**
     * The listener is to listen change on classify type ( uni, bi or multi-var)
     * @param a
     */
    public void addClassifyTypeChangeListener(ActionListener a){
        this.uniButton.addActionListener(a);
        this.multiButton.addActionListener(a);
        this.biButton.addActionListener(a);
    }

    public void itemStateChanged(ItemEvent e) {
        if (e.getStateChange() == e.SELECTED) {  // 
            //System.out.println(uniClassifier.getSelectedItem().toString().equals(JDMUnsupervisedAlgorithm.SELF_DEFINED));
            JComboBox source = (JComboBox)e.getItemSelectable();
            if (source == uniClassifier) {//jin: univar classifer ( classify method )
                if (!source.getSelectedItem().toString().equals(JDMUnsupervisedAlgorithm.SELF_DEFINED)) {
                    if (!uniNumc.isEnabled()) uniNumc.setEnabled(true);
                    if (dataset != null) fireAction();
                }
                else {
                    if (uniNumc.isEnabled()) {
                        uniNumc.setEnabled(false);
                        uniNumc.setValue(new Integer(this.boundaries.length-1));
                        if (dataset != null) fireAction();
                    }
                }
            }
            else if (source == biClassifier1) {
                if (!source.getSelectedItem().toString().equals(JDMUnsupervisedAlgorithm.SELF_DEFINED)) {
                    if (!biNumc1.isEnabled()) biNumc1.setEnabled(true);
                    if (dataset != null) fireAction();
                }
                else {
                    if (biNumc1.isEnabled()) {
                        biNumc1.setEnabled(false);
                        biNumc1.setValue(new Integer(this.boundariesX.length-1));
                        if (dataset != null) fireAction();
                    }
                }
            }
            else if (source == biClassifier2) {
                if (!source.getSelectedItem().toString().equals(JDMUnsupervisedAlgorithm.SELF_DEFINED)) {
                    if (!biNumc2.isEnabled()) biNumc2.setEnabled(true);
                    if (dataset != null) fireAction();
                }
                else {
                    if (biNumc2.isEnabled()) {
                        biNumc2.setEnabled(false);
                        biNumc2.setValue(new Integer(this.boundariesY.length-1));
                        if (dataset != null) fireAction();
                    }
                }
            }
            else if (source==uniAttrSel){ // 
                univarnameChanged();

            }
            else { // 
                if (dataset != null) fireAction();
            }
        }
    }

    /**
     *  
     */
    private void univarnameChanged() {
        Object varname = uniAttrSel.getSelectedItem();
        ((DefaultESVisualClassifier) vc).classifyOnVariableChanged(varname, false);
        /*ClassifySetting setting = ((DefaultESVisualClassifier) vc).getClassifySetting(varname);
        // 
        if(setting==null){//do classification using current GUI setting
            logger.log(" use GUI setting for "+varname,  VcAspect.classifySetting);
            fireAction();
        }
        else{
            logger.log( " use cached setting "+setting.toString(), VcAspect.classifySetting );
            this.doClassification(setting);
        }*/
    }






    /*******************************************************************************************************
     *                properties
     *******************************************************************************************************/
    /**
     *
     * @return
     */
    public ESVisualClassifier getVc() {
        return vc;
    }

    public void setVc(ESVisualClassifier vc) {
        this.vc = vc;
    }

    public JPanel getTypePanel() {
        return radioPanel;
    }
    public JPanel getParametersPanel(){
        return cards;
    }
    public String getClassifyType(){
        if(this.uniButton.isSelected()){
            return  UnsupervisedSettingsGUI.uniString;
        }
        else if (this.biButton.isSelected() ){
            return   UnsupervisedSettingsGUI.biString ;

        }
        else if(this.multiButton.isSelected() ){
            return UnsupervisedSettingsGUI.multiString ;
        }
        else{
            return "unknown";
        }
    }

    public AppDataModel getDataModel() {
        return dataModel;
    } /*******************************************************************************************************
 *                init components
 *******************************************************************************************************/
    /**
     * customized setting components after init
     */
    protected void setComponents(){
        // add Actionlistener and ChangeListener to those selectable component so that whenever the setting is changed, it do classification automatically
        // It enable us to remove the button panel
        ActionListener act=new ActionListener() {
            public void actionPerformed(ActionEvent evt) {
                fireAction();  //todo temp remove
            }
        };
        ChangeListener chg=new ChangeListener(){

            public void stateChanged(ChangeEvent e) {
                fireAction();
            }
        };

        this.biButton.addActionListener(act);//todo temp, for the first time switch,need generate classifications

        // 
        /*uniAttrSel.addActionListener(act);
        biAttrSel1.addActionListener(act);
        biAttrSel2.addActionListener(act);
        uniClassifier.addActionListener(act);
        biClassifier1.addActionListener(act);
        biClassifier2.addActionListener(act);*/

        uniNumc.addChangeListener(chg);
        biNumc1.addChangeListener(chg);
        biNumc2.addChangeListener(chg);
    }

    protected  void initComponents() {
        chooser = new JFileChooser();
        String[] filters = {"csv", "txt"};
        MyFileFilter filter = new MyFileFilter(filters);
        chooser.setDialogTitle("Open CSV data file");
        chooser.setFileFilter(filter);

        setLayout(new BorderLayout());
        /*setBorder(BorderFactory.createCompoundBorder(
        BorderFactory.createTitledBorder("Unsupervised Classification Settings"),
        BorderFactory.createEmptyBorder(5,5,5,5)));*/

        uniButton = new JRadioButton(uniString);
        //uniButton.setMnemonic(KeyEvent.VK_B);
        uniButton.setActionCommand(uniString);
        uniButton.addActionListener(this);
        uniButton.setSelected(true); //uniButton.
        biButton = new JRadioButton(biString);
        biButton.setActionCommand(biString);
        biButton.addActionListener(this);
        multiButton = new JRadioButton(multiString);
        multiButton.setActionCommand(multiString);
        multiButton.addActionListener(this);
        ButtonGroup radioGroup = new ButtonGroup();
        radioGroup.add(uniButton);
        radioGroup.add(biButton);
        radioGroup.add(multiButton);//radioGroup.getSelection().get
        radioPanel = new JPanel();
        TitledBorder titledBorder = DefaultESVisualClassifier.createTitledBorder("1. Set classification type");
        radioPanel.setBorder(BorderFactory.createCompoundBorder(
                titledBorder,
                BorderFactory.createEmptyBorder(5,5,5,5)));
        radioPanel.add(uniButton);
        radioPanel.add(biButton);
        // radioPanel.add(multiButton);  jin: for now not supported
        radioPanel.setAlignmentX(Component.CENTER_ALIGNMENT);
        add(radioPanel, BorderLayout.PAGE_START);

        uniAttrSel = new JComboBox();
        uniAttrSel.addItemListener(this);
        biAttrSel1 = new JComboBox();
        biAttrSel1.addItemListener(this);
        biAttrSel2 = new JComboBox();
        biAttrSel2.addItemListener(this);
        String[] names = {JDMUnsupervisedAlgorithm.EQUAL_INTERVAL, JDMUnsupervisedAlgorithm.MODIFIED_QUANTILES,
                JDMUnsupervisedAlgorithm.QUANTILES, JDMUnsupervisedAlgorithm.RAW_QUANTILES,
                JDMUnsupervisedAlgorithm.STANDARD_DEVIATION, JDMUnsupervisedAlgorithm.SELF_DEFINED, ClassifySetting.UNCLASSED };
        uniClassifier = new JComboBox(names);
        uniClassifier.addItemListener(this);
        biClassifier1 = new JComboBox(names);
        biClassifier1.addItemListener(this);
        biClassifier2 = new JComboBox(names);
        biClassifier2.addItemListener(this);
        String[] mNames = {JDMUnsupervisedAlgorithm.KMEANS};
        multiClassifier = new JComboBox(mNames);
        multiClassifier.addItemListener(this);
        uniNumc = new JSpinner(new SpinnerNumberModel(5,2,100,1));
        uniNumc.addChangeListener(this);
        biNumc1 = new JSpinner(new SpinnerNumberModel(5,2,100,1));
        biNumc1.addChangeListener(this);
        biNumc2 = new JSpinner(new SpinnerNumberModel(5,2,100,1));
        biNumc2.addChangeListener(this);
        multiNumc = new JSpinner(new SpinnerNumberModel(5,2,100,1));
        multiNumc.addChangeListener(this);

        JPanel cardUni = new JPanel(new GridBagLayout());
        GridBagConstraints c = new GridBagConstraints();
        c.fill = GridBagConstraints.BOTH;
        c.anchor = GridBagConstraints.LINE_START;
        c.gridx = 0;
        c.gridy = 0;
        c.insets = new Insets(5,5,5,5);
        cardUni.add(new JLabel("Attribute:"), c);
        c.anchor = GridBagConstraints.LINE_END;
        c.gridx = 1;
        c.gridy = 0;
        c.weightx = 0.6;
        cardUni.add(uniAttrSel, c);
        c.anchor = GridBagConstraints.LINE_START;
        c.gridx = 2;
        c.gridy = 0;
        c.weightx = 0.0;
        c.insets = new Insets(5,15,5,5);
        cardUni.add(new JLabel("Classifier:"), c);
        c.anchor = GridBagConstraints.LINE_END;
        c.gridx = 3;
        c.gridy = 0;
        c.insets = new Insets(5,5,5,5);
        cardUni.add(uniClassifier, c);
        //c.gridx = 4;
        //c.gridy = 0;
        //cardUni.add(Box.createRigidArea(new Dimension(20,5)), c);
        c.anchor = GridBagConstraints.LINE_START;
        c.gridx = 4;
        c.gridy = 0;
        c.insets = new Insets(5,15,5,5);
        cardUni.add(new JLabel("Class Count:"), c);
        c.anchor = GridBagConstraints.LINE_END;
        c.gridx = 5;
        c.gridy = 0;
        c.insets = new Insets(5,5,5,5);
        cardUni.add(uniNumc, c);

        JPanel cardBi = new JPanel(new GridBagLayout());
        //c.fill = GridBagConstraints.BOTH;
        c.anchor = GridBagConstraints.LINE_START;
        c.gridx = 0;
        c.gridy = 0;
        //c.insets = new Insets(5,5,5,5);
        cardBi.add(new JLabel("Attribute 1:"), c);
        c.anchor = GridBagConstraints.LINE_END;
        c.gridx = 1;
        c.gridy = 0;
        c.weightx = 0.6;
        cardBi.add(biAttrSel1, c);
        c.anchor = GridBagConstraints.LINE_START;
        c.gridx = 2;
        c.gridy = 0;
        c.weightx = 0.0;
        c.insets = new Insets(5,15,5,5);
        cardBi.add(new JLabel("Classifier 1:"), c);
        c.anchor = GridBagConstraints.LINE_END;
        c.gridx = 3;
        c.gridy = 0;
        c.insets = new Insets(5,5,5,5);
        cardBi.add(biClassifier1, c);
        //c.gridx = 4;
        //c.gridy = 0;
        //cardUni.add(Box.createRigidArea(new Dimension(20,5)), c);
        c.anchor = GridBagConstraints.LINE_START;
        c.gridx = 4;
        c.gridy = 0;
        c.insets = new Insets(5,15,5,5);
        cardBi.add(new JLabel("Class Count 1:"), c);
        c.anchor = GridBagConstraints.LINE_END;
        c.gridx = 5;
        c.gridy = 0;
        c.insets = new Insets(5,5,5,5);
        cardBi.add(biNumc1, c);
        c.anchor = GridBagConstraints.LINE_START;
        c.gridx = 0;
        c.gridy = 1;
        c.insets = new Insets(15,5,5,5);
        cardBi.add(new JLabel("Attribute 2:"), c);
        c.anchor = GridBagConstraints.LINE_END;
        c.gridx = 1;
        c.gridy = 1;
        c.weightx = 0.6;
        cardBi.add(biAttrSel2, c);
        c.anchor = GridBagConstraints.LINE_START;
        c.gridx = 2;
        c.gridy = 1;
        c.weightx = 0.0;
        c.insets = new Insets(15,15,5,5);
        cardBi.add(new JLabel("Classifier 2:"), c);
        c.anchor = GridBagConstraints.LINE_END;
        c.gridx = 3;
        c.gridy = 1;
        c.insets = new Insets(15,5,5,5);
        cardBi.add(biClassifier2, c);
        //c.gridx = 4;
        //c.gridy = 0;
        //cardUni.add(Box.createRigidArea(new Dimension(20,5)), c);
        c.anchor = GridBagConstraints.LINE_START;
        c.gridx = 4;
        c.gridy = 1;
        c.insets = new Insets(15,15,5,5);
        cardBi.add(new JLabel("Class Count 2:"), c);
        c.anchor = GridBagConstraints.LINE_END;
        c.gridx = 5;
        c.gridy = 1;
        c.insets = new Insets(15,5,5,5);
        cardBi.add(biNumc2, c);

        JPanel cardMulti = new JPanel(new GridBagLayout());
        c.anchor = GridBagConstraints.LINE_START;
        c.gridx = 0;
        c.gridy = 0;
        c.insets = new Insets(5,5,5,15);
        c.anchor = GridBagConstraints.LINE_START;
        attselBtn = new JButton("Select Attributes");
        attselBtn.addActionListener(this);
        cardMulti.add(attselBtn, c);
        c.gridx = 1;
        c.gridy = 0;
        c.insets = new Insets(5,5,5,5);
        cardMulti.add(new JLabel("Classifier:"), c);
        c.anchor = GridBagConstraints.LINE_END;
        c.gridx = 2;
        c.gridy = 0;
        c.insets = new Insets(5,5,5,15);
        cardMulti.add(multiClassifier, c);
        //c.gridx = 3;
        //c.gridy = 0;
        //cardMulti.add(Box.createRigidArea(new Dimension(20,5)), c);
        c.anchor = GridBagConstraints.LINE_START;
        c.gridx = 3;
        c.gridy = 0;
        c.insets = new Insets(5,5,5,5);
        cardMulti.add(new JLabel("Class Count:"), c);
        c.anchor = GridBagConstraints.LINE_END;
        c.gridx = 4;
        c.gridy = 0;
        //c.insets = new Insets(0,0,5,0);
        cardMulti.add(multiNumc, c);

        cards = new JPanel(new CardLayout());    ////
        TitledBorder titledBorder2 = DefaultESVisualClassifier.createTitledBorder("2. Set classification parameters");
        cards.setBorder(BorderFactory.createCompoundBorder(
                titledBorder2,
                BorderFactory.createEmptyBorder(5,5,5,5)));
        cards.add(cardUni, uniString);
        cards.add(cardBi, biString);
        cards.add(cardMulti, multiString);
        add(cards, BorderLayout.CENTER);
        activeCardPanel = uniString;
        /* //Jin: remove button panel
        openBtn = new JButton("Open File...");
        openBtn.addActionListener(this);

        loadBtn = new JButton("Load");
        loadBtn.addMouseListener(new java.awt.event.MouseAdapter() {
        public void mouseClicked(java.awt.event.MouseEvent evt) {
        fireAction();
        }
        });
        JPanel btnPane = new JPanel();
        btnPane.add(openBtn);
        btnPane.add(new JLabel("     "));
        btnPane.add(loadBtn);
        add(btnPane, BorderLayout.PAGE_END); */
        //add(Box.createRigidArea(new Dimension(0,5)));

        //int w = (int)cards.getPreferredSize().getWidth() + 10;
        //int h = (int)radioPanel.getPreferredSize().getHeight() +
        //(int)cards.getPreferredSize().getHeight() +
        //(int)btnPane.getPreferredSize().getHeight() + 20;
       
        setPreferredSize(new Dimension(700, 200));
    }

  

}



